package com.echo.im.engin.netty.processor.impl.in;

import com.alibaba.fastjson2.JSONObject;
import com.echo.im.common.enums.IMCmdType;
import com.echo.im.domain.common.MessageDTO;
import com.echo.im.domain.privates.dto.PrivateMessagePacket;
import com.echo.im.domain.privates.message.PrivateMessageService;
import com.echo.im.engin.netty.processor.preprocessor.PreprocessorContext;
import com.echo.im.engin.netty.processor.MessageInProcessor;
import io.netty.channel.ChannelHandlerContext;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

/**
 * @author: echo
 * @time: 2024-08-22
 */
@Component
@RequiredArgsConstructor
public class PrivateMessageInProcessor implements MessageInProcessor<PrivateMessagePacket> {

    private final PrivateMessageService privateMessageService;

    private final PreprocessorContext preprocessorContext;

    @Override
    public void inProcess(ChannelHandlerContext ctx, PrivateMessagePacket packet) {
        //这里浓缩了所有精华
        //私聊消息有很多指令  消息类型 0:文字 1:图片 2:文件 3:语音 4:视频 10:撤回 11:已读 12:状态变更（上线或者下线）
        //回到原理来说，所有的messageType和内容是高度耦合的，但是我们服务端并不处理这些耦合
        //所有的messageType的语义都放到客户端实现，我们服务端只负责转发
        //然后当我们将消息进行离线存储逻辑或者对方收到并且接收方回复ack的时候，只是对seq进行回复，并且对此seq声明messageId
        //保证了messageId由服务器生成
        //所以这就保证了私聊消息必达

        //然后我们这里还要做一些修改，也是一些元信息
        //消息是否需要赋予id？如果是临时消息，就不要有id了，例如上线下线，也不进入离线逻辑
        //所以 1、是否需要id 2、是否进入离线逻辑 3、是否持久化 4、双方是否需要时好友

        //如果是撤回消息或已读消息这些指令我们直接在仓储的时候修改数据库，没必要直接在我们现在的主要业务中修改数据库
        MessageDTO<PrivateMessagePacket> messageDTO = new MessageDTO<>();

        messageDTO.setPacket(packet);

        preprocessorContext.doPreprocess(messageDTO);

        privateMessageService.sendMessage(messageDTO);

    }

    @Override
    public IMCmdType getCmdType() {
        return IMCmdType.PRIVATE_MESSAGE;
    }

    @Override
    public PrivateMessagePacket transForm(Object o) {
        return ((JSONObject) o).toJavaObject(PrivateMessagePacket.class);
    }


}
